package com.thexb.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.thexb.common.JwtUtil;
import com.thexb.sys.entity.Menu;
import com.thexb.sys.entity.User;
import com.thexb.sys.entity.UserRole;
import com.thexb.sys.mapper.UserMapper;
import com.thexb.sys.service.IMenuService;
import com.thexb.sys.service.IUserRoleService;
import com.thexb.sys.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author thexb
 * @since 2023-04-04
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private IUserRoleService iUserRoleService;

    @Resource
    private RedisTemplate<String, User> redisTemplate;


    @Resource
    private IMenuService iMenuService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil coderJwt;
    @Override
    public HashMap<String, Object> login(User user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, user.getUsername());
        User loginUser = userMapper.selectOne(queryWrapper);
        // 如果没有用户
        if (loginUser == null) {
            return null;
        }
        if (!passwordEncoder.matches(user.getPassword(), loginUser.getPassword())) {
            return null;
        }
        // JWT存储数据
        loginUser.setPassword(null);
        String token = coderJwt.createToken(loginUser);
        // 返回数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        return map;
    }

    @Override
    public HashMap<String, Object> getInfo(String token) {
        User user = null;
        try {
            // 解析JWT
            user = coderJwt.parseToken(token, User.class);
        } catch (Exception e) {
            return null;
        }
        // 用户信息
        HashMap<String, Object> info = new HashMap<>();
        info.put("name", user.getUsername());
        info.put("avatar", user.getAvatar());
        // 角色
        List<String> roles = userMapper.getRoleNameByUserId(user.getId());
        info.put("roles", roles);
        // 查询菜单
        List<Menu> loginMenu = iMenuService.getLoginMenu(user.getId());
        info.put("menuList", loginMenu);
        return info;
    }

    @Override
    public void logout(String token) {
        // 不用删除redis
        // redisTemplate.delete(token);
    }

    @Override
    @Transactional
    public void addUser(User user) {
        // 保存用户
        this.save(user);
        // 保存角色
        for (int roleId : user.getRoleIds()) {
            iUserRoleService.save(new UserRole(null, user.getId(), roleId));
        }
    }

    @Override
    public User getUser(int id) {
        // 查询用户
        User user = this.getById(id);
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, id);
        // 查询角色
        List<UserRole> list = iUserRoleService.list(wrapper);
        List<Integer> collect = list.stream().map(UserRole::getRoleId).toList();
        user.setRoles(collect);
        return user;
    }

    @Override
    @Transactional
    public void updateUser(User user) {
        // 更新用户
        this.updateById(user);
        // 删除所有role
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, user.getId());
        iUserRoleService.remove(wrapper);
        // 添加新的role
        for (int roleId : user.getRoleIds()) {
            iUserRoleService.save(new UserRole(null, user.getId(), roleId));
        }
    }

    @Override
    @Transactional
    public void removeUser(int id) {
        this.removeById(id);
        // 删除所有role
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, id);
        iUserRoleService.remove(wrapper);
    }
}
